<template>
  <div style="background-color:#fff;padding:20px;">
    <!-- 条件查询的表单项 -->
    <div>
      <el-form-item label="角色名称">
        <el-input v-model="keyword" placeholder="角色名称" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="initPageData">搜索</el-button>
        <el-button @click="handleReset">重置</el-button>
      </el-form-item>
    </div>
    <!-- 新增按钮 -->
    <div>
      <el-button type="success" size="small" @click="handleShowSaveDialog">
        添加
      </el-button>
    </div>
    <!-- 角色分页列表表格 -->
    <div>
      <el-table :data="roles" stripe style="width: 100%">
        <el-table-column prop="roleName" label="角色名称" />
        <el-table-column prop="roleCode" label="角色code" />
        <el-table-column prop="description" label="角色介绍" />
        <el-table-column prop="createTime" label="创建时间" />
        <el-table-column label="操作">
          <template #default="scope">
            <el-button size="small" @click="handleEdit(scope.row)">
              修改
            </el-button>
            <el-button
              size="small"
              type="danger"
              @click="handleDelete(scope.row)"
            >
              删除
            </el-button>
            <el-button
              size="small"
              type="warning"
              @click="handleShowAssignMenusDialog(scope.row)"
            >
              分配菜单
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin-top:20px;text-align:center">
        <el-pagination
          v-model:current-page="pageNum"
          v-model:page-size="pageSize"
          :page-sizes="[1, 2, 3, 4, 5]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="initPageData"
          @current-change="initPageData"
        />
      </div>
    </div>

    <!-- 新增角色的对话框 -->
    <div>
      <el-dialog v-model="dialogFormVisible" :title="title">
        <el-form :model="role">
          <el-form-item label="角色名称" :label-width="formLabelWidth">
            <el-input v-model="role.roleName" autocomplete="off" />
          </el-form-item>
          <el-form-item label="角色Code" :label-width="formLabelWidth">
            <el-input v-model="role.roleCode" autocomplete="off" />
          </el-form-item>
          <el-form-item label="角色介绍" :label-width="formLabelWidth">
            <el-input v-model="role.description" autocomplete="off" />
          </el-form-item>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="handleSaveOrUpdateRole">
              提交
            </el-button>
          </div>
        </template>
      </el-dialog>
    </div>

    <!-- 给角色分配菜单的对话框 -->
    <div>
      <el-dialog v-model="assignMenusDialogFormVisible" title="分配菜单">
        <el-form>
          <el-tree
            ref="menuTree"
            style="max-width: 600px"
            :data="menus"
            show-checkbox
            node-key="id"
            :default-expand-all="true"
            :default-checked-keys="checkedMenuIds"
            :props="defaultProps"
          />
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button @click="assignMenusDialogFormVisible = false">
              取消
            </el-button>
            <el-button type="primary" @click="handleAssignMenus2Role">
              提交
            </el-button>
          </div>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<script setup>
import {
  GetRolePage,
  SaveRole,
  DeleteRole,
  GetRoleById,
  UpdateRole,
  AssignMenus2Role,
} from '@/api/sysRole'
import { GetMenusAndAssignedMenuIds } from '@/api/sysMenu'
import { onMounted, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
//在页面初始化时 加载第一页数据展示
onMounted(() => {
  initPageData()
})
//分配菜单的对话框属性和函数
const menuTree = ref({}) //用来绑定vue渲染的一个组件
const checkedMenuIds = ref([])
const assignMenusDialogFormVisible = ref(false)
//菜单列表
// 分配菜单需要的数据：
// 1、所有的可用菜单列表   2、角色已拥有的非一级菜单id列表
const menus = ref([])
//tree控件的配置
const defaultProps = {
  children: 'children',
  label: 'title', //标题属性
}
//分配角色对话框：提交按钮事件函数
const handleAssignMenus2Role = async () => {
  let roleId = role.value.id
  //获取Tree控件中选中的节点的 node-key的值  菜单id
  let checkedMenuIds = menuTree.value.getCheckedKeys()
  let halfCheckedMenuIds = menuTree.value.getHalfCheckedKeys()
  // console.log(roleId, checkedMenuIds, halfCheckedMenuIds)
  //将checkedMenuIds和halfCheckedMenuIds中的所有元素拷贝给menuIds
  let menuIds = [...checkedMenuIds, ...halfCheckedMenuIds]
  await AssignMenus2Role(roleId, menuIds)
  ElMessage.success('分配菜单成功')
  assignMenusDialogFormVisible.value = false
}

//给角色分配菜单按钮事件函数： 查询展示所有菜单以及选中该角色已拥有的菜单 弹出对话框
const handleShowAssignMenusDialog = async row => {
  // 缓存要分配菜单的角色对象
  role.value = row
  //清除缓存
  checkedMenuIds.value = []
  menus.value = []
  //row.id 是角色id，可以根据角色id查询已分配的非一级菜单id列表  和所有的可以用的菜单集合
  const { data } = await GetMenusAndAssignedMenuIds(row.id)
  menus.value = data.menus
  checkedMenuIds.value = data.menuIds
  assignMenusDialogFormVisible.value = true
}

//声明分页需要的变量
let pageNum = ref(1)
let pageSize = ref(3)
let total = ref(0)
let keyword = ref(null)
let roles = ref([])
//分页导航的事件函数
const initPageData = async () => {
  const { code, message, data } = await GetRolePage(
    pageNum.value,
    pageSize.value,
    keyword.value
  )
  roles.value = data.page.list
  total.value = data.page.total
  //   console.log(code, message, data.page.list)
}
//条件搜索  重置按钮事件函数
const handleReset = () => {
  keyword.value = null
  pageNum.value = 1
  pageSize.value = 3
  initPageData()
}
//新增角色对话框属性和函数
const dialogFormVisible = ref(false)
const role = ref({})
const formLabelWidth = ref('120px')
const title = ref('新增角色')
const handleShowSaveDialog = () => {
  //清空缓存
  role.value = {}
  title.value = '新增角色'
  //弹出新增对话框
  dialogFormVisible.value = true
}
//新增/更新角色表单提交按钮事件函数
const handleSaveOrUpdateRole = () => {
  if (role.value.id) {
    //更新
    handleUpdateRole()
  } else {
    //新增
    handleSaveRole()
  }
}
//新增角色
const handleSaveRole = async () => {
  //提交请求
  const { code, message, data } = await SaveRole(role.value)
  //成功提示
  ElMessage.success('新增角色成功')
  //刷新页面数据
  initPageData()
  //关闭新增对话框
  dialogFormVisible.value = false
}
//更新角色
const handleUpdateRole = async () => {
  await UpdateRole(role.value)
  //弹出提示
  ElMessage.success('更新成功')
  //刷新数据
  initPageData()
  //关闭对话框
  dialogFormVisible.value = false
}
//表格数据： 删除按钮事件函数
const handleDelete = row => {
  ElMessageBox.confirm(`是否删除角色【${row.roleName}】?`, '删除确认', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const { code, message } = await DeleteRole(row.id)
      if (+code === 200) {
        ElMessage({
          type: 'success',
          message: '删除成功',
        })
        initPageData()
      } else {
        ElMessage.error(message)
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除',
      })
    })
}
//表格数据： 修改按钮事件函数
const handleEdit = async row => {
  //查询要修改的数据在新增/修改的 对话框中回显
  const { data } = await GetRoleById(row.id)
  role.value = data.item
  //弹出对话框
  title.value = '修改角色'
  dialogFormVisible.value = true
}
</script>
